package com.srmt.common.config;

import com.srmt.common.ratelimit.config.RateLimitConfig;
import com.srmt.common.retry.RetryConfig;

import java.util.*;

/**
 * 统一的应用配置类
 * 包含所有配置项，从单一配置文件加载
 *
 * @author SRMT Development Team
 * @since 2.0.0
 * @version 3.0.0 统一使用RateLimitConfig和RetryConfig，移除内部重复定义
 */
public class ApplicationConfig {

    // ========== 服务配置 ==========
    private ServiceSettings service = new ServiceSettings();

    // ========== 飞书配置 ==========
    private FeishuSettings feishu = new FeishuSettings();

    // ========== 限流配置 ==========
    private RateLimitConfig rateLimit = new RateLimitConfig();

    // ========== 重试配置 ==========
    private RetryConfig retry = new RetryConfig();
    
    
    /**
     * 服务配置
     */
    public static class ServiceSettings {
        private String platform = "feishu";
        private int timeout = 10000; // 毫秒
        private boolean logReqAtDebug = true;
        private CacheSettings cache = new CacheSettings();
        
        public static class CacheSettings {
            private boolean enabled = true;
            private int size = 1000;
            private int ttlMinutes = 60;
            
            // Getters and Setters
            public boolean isEnabled() { return enabled; }
            public void setEnabled(boolean enabled) { this.enabled = enabled; }
            
            public int getSize() { return size; }
            public void setSize(int size) { this.size = size; }
            
            public int getTtlMinutes() { return ttlMinutes; }
            public void setTtlMinutes(int ttlMinutes) { this.ttlMinutes = ttlMinutes; }
        }
        
        // Getters and Setters
        public String getPlatform() { return platform; }
        public void setPlatform(String platform) { this.platform = platform; }
        
        public int getTimeout() { return timeout; }
        public void setTimeout(int timeout) { this.timeout = timeout; }
        
        public boolean isLogReqAtDebug() { return logReqAtDebug; }
        public void setLogReqAtDebug(boolean logReqAtDebug) { this.logReqAtDebug = logReqAtDebug; }
        
        public CacheSettings getCache() { return cache; }
        public void setCache(CacheSettings cache) { this.cache = cache; }
    }
    
    /**
     * 飞书平台配置
     */
    public static class FeishuSettings {
        private String appId;
        private String appSecret;
        private String baseUrl = "https://open.feishu.cn";
        private String defaultFolderToken = "";  // 默认文件夹token
        
        // Getters and Setters
        public String getAppId() { return appId; }
        public void setAppId(String appId) { this.appId = appId; }
        
        public String getAppSecret() { return appSecret; }
        public void setAppSecret(String appSecret) { this.appSecret = appSecret; }
        
        public String getBaseUrl() { return baseUrl; }
        public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; }
        
        public String getDefaultFolderToken() { return defaultFolderToken; }
        public void setDefaultFolderToken(String defaultFolderToken) { this.defaultFolderToken = defaultFolderToken; }
        
        /**
         * 验证飞书配置
         */
        public void validate() {
            if (appId == null || appId.trim().isEmpty()) {
                throw new IllegalStateException("飞书应用ID不能为空");
            }
            if (appSecret == null || appSecret.trim().isEmpty()) {
                throw new IllegalStateException("飞书应用密钥不能为空");
            }
        }
    }
    
    
    
    // ========== 主类 Getters and Setters ==========
    
    public ServiceSettings getService() { return service; }
    public void setService(ServiceSettings service) { this.service = service; }
    
    public FeishuSettings getFeishu() { return feishu; }
    public void setFeishu(FeishuSettings feishu) { this.feishu = feishu; }
    
    public RateLimitConfig getRateLimit() { return rateLimit; }
    public void setRateLimit(RateLimitConfig rateLimit) { this.rateLimit = rateLimit; }

    public RetryConfig getRetry() { return retry; }
    public void setRetry(RetryConfig retry) { this.retry = retry; }
    
    
    /**
     * 验证配置完整性
     */
    public void validate() {
        // 验证服务配置
        if (service.getPlatform() == null || service.getPlatform().trim().isEmpty()) {
            throw new IllegalStateException("服务平台不能为空");
        }
        
        if (service.getTimeout() <= 0) {
            throw new IllegalStateException("服务 timeout must be positive");
        }
        
        // 验证飞书配置（如果平台是飞书）
        if ("feishu".equalsIgnoreCase(service.getPlatform())) {
            feishu.validate();
        }
        
        // 验证缓存配置
        if (service.getCache().isEnabled()) {
            if (service.getCache().getSize() <= 0) {
                throw new IllegalStateException("缓存 size must be positive when cache is enabled");
            }
            if (service.getCache().getTtlMinutes() <= 0) {
                throw new IllegalStateException("缓存 TTL must be positive when cache is enabled");
            }
        }
        
        // 验证限流配置
        if (rateLimit.isEnabled()) {
            if (rateLimit.getDefaultQps() <= 0) {
                throw new IllegalStateException("启用限流时默认QPS必须为正数");
            }
        }

        // 验证重试配置
        if (retry.isEnabled()) {
            if (retry.getMaxAttempts() <= 0) {
                throw new IllegalStateException("最大重试次数必须为正数");
            }
            if (retry.getInitialDelayMs() < 0) {
                throw new IllegalStateException("初始重试延迟不能为负数");
            }
            if (retry.getBackoffFactor() <= 0) {
                throw new IllegalStateException("退避因子必须为正数");
            }
        }
    }
    
    /**
     * 创建默认配置
     */
    public static ApplicationConfig createDefault() {
        return new ApplicationConfig();
    }
    
    /**
     * 复制配置（深拷贝）
     */
    public ApplicationConfig copy() {
        ApplicationConfig copy = new ApplicationConfig();

        // 复制服务配置
        copy.service.setPlatform(this.service.getPlatform());
        copy.service.setTimeout(this.service.getTimeout());
        copy.service.setLogReqAtDebug(this.service.isLogReqAtDebug());
        copy.service.getCache().setEnabled(this.service.getCache().isEnabled());
        copy.service.getCache().setSize(this.service.getCache().getSize());
        copy.service.getCache().setTtlMinutes(this.service.getCache().getTtlMinutes());

        // 复制飞书配置
        copy.feishu.setAppId(this.feishu.getAppId());
        copy.feishu.setAppSecret(this.feishu.getAppSecret());
        copy.feishu.setBaseUrl(this.feishu.getBaseUrl());
        copy.feishu.setDefaultFolderToken(this.feishu.getDefaultFolderToken());

        // 复制限流配置（包括自定义限流器）
        copy.rateLimit.setEnabled(this.rateLimit.isEnabled());
        copy.rateLimit.setDefaultQps(this.rateLimit.getDefaultQps());
        copy.rateLimit.setDefaultRetryTimeout(this.rateLimit.getDefaultRetryTimeout());
        copy.rateLimit.setDefaultMaxRetries(this.rateLimit.getDefaultMaxRetries());
        copy.rateLimit.setApiConfigs(new HashMap<>(this.rateLimit.getApiConfigs()));
        copy.rateLimit.setProperties(new HashMap<>(this.rateLimit.getProperties()));
        copy.rateLimit.setCustomRateLimiter(this.rateLimit.getCustomRateLimiter());

        // 复制重试配置
        copy.retry.setEnabled(this.retry.isEnabled());
        copy.retry.setMaxAttempts(this.retry.getMaxAttempts());
        copy.retry.setInitialDelayMs(this.retry.getInitialDelayMs());
        copy.retry.setMaxDelayMs(this.retry.getMaxDelayMs());
        copy.retry.setBackoffFactor(this.retry.getBackoffFactor());


        return copy;
    }

    /**
     * 创建配置构建器
     */
    public static ApplicationConfigBuilder builder() {
        return new ApplicationConfigBuilder();
    }

    /**
     * 配置构建器
     */
    public static class ApplicationConfigBuilder {
        private ApplicationConfig config = new ApplicationConfig();

        public ApplicationConfigBuilder withService(String platform, int timeout) {
            config.getService().setPlatform(platform);
            config.getService().setTimeout(timeout);
            return this;
        }

        public ApplicationConfigBuilder withFeishu(String appId, String appSecret) {
            config.getFeishu().setAppId(appId);
            config.getFeishu().setAppSecret(appSecret);
            return this;
        }

        public ApplicationConfigBuilder withFeishu(String appId, String appSecret, String baseUrl) {
            config.getFeishu().setAppId(appId);
            config.getFeishu().setAppSecret(appSecret);
            config.getFeishu().setBaseUrl(baseUrl);
            return this;
        }

        public ApplicationConfigBuilder withCache(boolean enabled, int size, int ttlMinutes) {
            config.getService().getCache().setEnabled(enabled);
            config.getService().getCache().setSize(size);
            config.getService().getCache().setTtlMinutes(ttlMinutes);
            return this;
        }

        public ApplicationConfigBuilder withRateLimit(boolean enabled, int defaultQps) {
            config.getRateLimit().setEnabled(enabled);
            config.getRateLimit().setDefaultQps(defaultQps);
            return this;
        }

        public ApplicationConfigBuilder withRetry(boolean enabled, int maxAttempts) {
            config.getRetry().setEnabled(enabled);
            config.getRetry().setMaxAttempts(maxAttempts);
            return this;
        }

        /**
         * 设置自定义限流器（用于分布式限流场景）
         *
         * @param customRateLimiter 自定义限流器实例（如 RedisRateLimiter）
         * @return Builder实例
         */
        public ApplicationConfigBuilder withCustomRateLimiter(com.srmt.common.ratelimit.RateLimiter customRateLimiter) {
            config.getRateLimit().setCustomRateLimiter(customRateLimiter);
            return this;
        }

        public ApplicationConfigBuilder forProduction() {
            config.getService().getCache().setEnabled(true);
            config.getService().getCache().setSize(1000);
            config.getService().getCache().setTtlMinutes(60);
            config.getService().setTimeout(10000);
            config.getRateLimit().setEnabled(true);
            config.getRetry().setEnabled(true);
            return this;
        }

        public ApplicationConfigBuilder forDevelopment() {
            config.getService().getCache().setEnabled(false);
            config.getService().getCache().setTtlMinutes(5);
            config.getService().setTimeout(30000);
            config.getRateLimit().setEnabled(false);
            config.getRetry().setEnabled(false);
            return this;
        }

        public ApplicationConfigBuilder forTesting() {
            config.getService().getCache().setEnabled(false);
            config.getService().setTimeout(30000);
            config.getRateLimit().setEnabled(true);
            config.getRetry().setEnabled(false);
            return this;
        }

        public ApplicationConfig build() {
            config.validate();
            return config;
        }
    }
}